/*  WinKawaks 1.62模拟器的战国传承3的脚本,功能是连发拳,连发武器,一键空中连击,一键大必杀,一键重踢+下下斩忍术,另加入numpad0暂停功能.
  按键设定在全局变量那里,各种操作延时,以及我优化后的参数都在全局变量和注释.
  在Gui修改参数的话,必须要Submit_才能生效.按键调用了我自己制作的Key相关函数,都是些常用功能,顺便测试了外部文件调用与函数引用.
  脚本测试后觉得效果不错.
  
  By setycyas, 2022-09-21
*/
SendMode Input ; 此模式对WinKawaks有效

/* 调用自制的按键相关函数 
*/
#Include D:\software\AutoHotkey\MyAHK\MyAhkModules\MyKey.ahk ;按键相关库,所有函数导出到MyKey对象中

/* 常量,CT = const,部分常量因为使用的地方无法引用对象,只能用以CT开头的变量重复代替
*/ {
CT := object()
CT.punchKey := "c", ;拳按键
CT.weaponKey := "x", ;武器按键
CT.macro12 := "t" ;12键一起按的宏 
CT.punchDuration := 100 ;按住拳键的持续时间
CT.weaponDuration := 150 ;按住武器键的持续时间
CT.punchDelay := 50 ;拳的连发延时,定义为上一次松开键到下一次按键的时间

;以下是用CT开头重复制作的常量,用于无法引用对象的地方
CTmacro12 := CT.macro12
CTweaponKey := CT.weaponKey
}

/* 一般全局变量,GV = global Variables,在接收gui输入后重新设定,见函数makeData()
*/ {
GV := object()
GV.jumpAtType := 1 ;空中连击开始类型,0为飞踢,1为武器
GV.weaponDelayArr := [] ;武器连发延时数组,由于要直接使用,记录的是上次松开键到下次按下键的时间
GV.jumpAtDelayArr := [] ;空中连击延时数组,由于要直接使用,记录的是上次松开键到下次按下键的时间
}

/* 接收Gui输入的全局变量,以G=gui 开头,无法打包到object中
*/ {
;武器的连发延时设定,这里的延时定义为从上次按下键到下一次按下键.
;测试结果:红,金鹰,影连,白鬼,阿国-390,420,330;金刚-390,420,360
GweaponDelays := "390,420,330" 

;空中连击参数组,第一个数字为0或1,表示空中连击是以飞踢开始还是武器开始,0为飞踢,1为武器
;后面的几个数字是连击延时,这里延时定义为从上次按下键到下一次按下键,数字的个数决定连击次数,连击次数比数字个数多1
;测试后发现稳健的方法是:
;红:1;300,300,300(此参数其他人也还行) 影连,白鬼:1;350,350 金鹰,阿国:0;250,300,250
GjumpAtParams := "1;300,300,300" 

}

/* 自定义函数
*/ {
  
;缩短MyKey的press函数名
press(key, pressDuration := 100){
  global MyKey
  return MyKey.press.Call(key, pressDuration)
}

;缩短MyKey的waitKeyUp函数名
waitKeyUp(key, waitTime, waitDuration := 60){
  global MyKey
  return MyKey.waitKeyUp.Call(key, waitTime, waitDuration)
}

;根据在Gui中输入的数据,制作全局变量数据
makeData(){
  global CT
  global GV
  global GweaponDelays
  global GjumpAtParams
  
  ;制作武器延时数组,因为直接使用必须计算出上次松开键到下次按键的时间
  GV.weaponDelayArr := StrSplit(GweaponDelays, ",")
  for k, v in GV.weaponDelayArr {
    GV.weaponDelayArr[k] := v-CT.weaponDuration
  }
  
  ;制作空中连击需要的数据
  tempArr := StrSplit(GjumpAtParams, ";")
  GV.jumpAtType := tempArr[1]
  atType := GV.jumpAtType
  GV.jumpAtDelayArr := StrSplit(tempArr[2], ",")
  for k, v in GV.jumpAtDelayArr {
    if (atType) {
      GV.jumpAtDelayArr[k] := v-CT.weaponDuration
    }else{
      GV.jumpAtDelayArr[k] := v-CT.punchDuration
    }
    atType := !atType
  }
  
  return
}

}

/* 加入Gui并制作全局变量
*/ {
Gui, Add, Text, , weapon delays:
Gui, Add, Edit, vGweaponDelays, %GweaponDelays%
Gui, Add, Text, , jump attack params:
Gui, Add, Edit, vGjumpAtParams, %GjumpAtParams%
Gui, Add, Button, , Submit_ ;提交
Gui, Add, Button, , Exit ;结束app
Gui, Show,w250h150, WinKawaks - sengoku3
makeData()
return
}

/* Gui响应
*/ {
ButtonSubmit_: 
Gui, Submit,NoHide ; 保存用户输入后每个控件的数据,NoHide可以在提交数据后保持窗体显示
makeData()
MsgBox, You have submit your changes!
return

ButtonExit: 
ExitApp
return
}

/* 快捷键处理
*/
#IfWinActive, ahk_exe WinKawaks.exe
;连发拳,为防止死循环,有最大次数限制,放开键则停止:
~w::
{
loop, 10 {
  press(CT.punchKey, CT.punchDuration)
  if (!GetKeyState("w")) {
    break
  }
  sleep, % CT.punchDelay
}
return
}

;剑连发,按照GweaponDelays的延时进行连击
~s::
{
press(CT.weaponKey, CT.weaponDuration) ;必须持续按长时间,太短会无法反应!因为武器出手时间长
for k, v in GV.weaponDelayArr {
  isSUp := waitKeyUp("s", v)
  if (isSUp) {
    break
  }else{
    press(CT.weaponKey, CT.weaponDuration)
  }
}
return
}

;空中连击
~q::
{
atType := GV.jumpAtType ;攻击类型
for k, v in GV.jumpAtDelayArr {
  if (atType) {
    press(CT.weaponKey, CT.weaponDuration)
  } else {
    press(CT.punchKey, CT.punchDuration)
  }  
  sleep, %v%
  atType := !atType
}
if (atType) {
    press(CT.weaponKey, CT.weaponDuration)
  } else {
    press(CT.punchKey, CT.punchDuration)
  }  
return
}

;大忍术或影连,金刚的投技忍术
~r::
{
press("down", 50)
sleep, 50
send {up down}
sleep, 50
send {%CTmacro12% down}
sleep, 50
send {up up}
send {%CTmacro12% up}
return
}

;重踢后立即连下下武器忍术
~a:: 
{
press(CT.punchKey, CT.punchDuration)
sleep, 200
press("down", 50)
sleep, 50
send {down down}
sleep, 50
send {%CTweaponKey% down}
sleep, 50
send {down up}
send {%CTweaponKey% up}
return
}

;暂停
~numpad0::
{
press("Enter")
return
}

#IfWinActive
